package com.meisupic.copyright.service.impl;

import static com.meisupic.copyright.common.AuthorizeRuleEnum.ExclusiveAuthorize;
import static com.meisupic.copyright.common.AuthorizeRuleEnum.NonExclusiveAuthorize;
import static com.meisupic.copyright.common.AuthorizeRuleEnum.OfflineAuthorize;
import static com.meisupic.copyright.common.Constants.APPLY_TYPE_AGENT;
import static com.meisupic.copyright.common.Constants.AUTH_TYPE_PERSON;
import static com.meisupic.copyright.common.Constants.CERTIFICATE_FILE_PATH;
import static com.meisupic.copyright.common.Constants.COMMITMENT;
import static com.meisupic.copyright.common.Constants.CREATIVENATURE_ORIGINAL;
import static com.meisupic.copyright.common.Constants.OSS_HOST;
import static com.meisupic.copyright.common.Constants.PUBLISH_STATUS_PUBLISHED;
import static com.meisupic.copyright.common.Constants.PUBLISH_STATUS_UNPUBLISHED;
import static com.meisupic.copyright.common.Constants.RIGHT_FETCH_MODE_ORIGINAL_ACQUISITION;
import static com.meisupic.copyright.common.Constants.RIGHT_OWN_MODE_LEGAL_WORKS;
import static com.meisupic.copyright.common.Constants.RIGHT_OWN_MODE_PERSONAL_WORKS;
import static com.meisupic.copyright.common.Constants.WORKS_DIR;
import static com.yuanbenlian.service.ECKeyProcessor.GeneratorSecp256k1Key;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.meisupic.copyright.common.AuthorizeRuleEnum;
import com.meisupic.copyright.common.Constants;
import com.meisupic.copyright.common.WorksProcessDetailEnum;
import com.meisupic.copyright.common.WorksProcessEnum;
import com.meisupic.copyright.domain.bo.Applyer;
import com.meisupic.copyright.domain.bo.Attachment;
import com.meisupic.copyright.domain.bo.DCIWorksRegisterBo;
import com.meisupic.copyright.domain.bo.ImageInfo;
import com.meisupic.copyright.domain.bo.Productauthor;
import com.meisupic.copyright.domain.bo.Proxy;
import com.meisupic.copyright.domain.bo.RCodeRegisterBo;
import com.meisupic.copyright.domain.bo.RCodeReplyBo;
import com.meisupic.copyright.domain.bo.RCodeUpdateBo;
import com.meisupic.copyright.domain.po.Category;
import com.meisupic.copyright.domain.po.CopyRightWorks;
import com.meisupic.copyright.domain.po.CopyrightWorksAuditRecord;
import com.meisupic.copyright.domain.po.Goods;
import com.meisupic.copyright.domain.po.RealNameAuth;
import com.meisupic.copyright.domain.po.Users;
import com.meisupic.copyright.domain.query.WorksQuery;
import com.meisupic.copyright.domain.vo.CategroyVo;
import com.meisupic.copyright.domain.vo.CopyRightWorksResponseVo;
import com.meisupic.copyright.domain.vo.CopyRightWorksRowVo;
import com.meisupic.copyright.domain.vo.CopyRightWorksVo;
import com.meisupic.copyright.domain.vo.DciCallbackMessageVo;
import com.meisupic.copyright.domain.vo.RegisterCallBackParamsVo;
import com.meisupic.copyright.domain.vo.ReturnToDciMessageVo;
import com.meisupic.copyright.domain.vo.WorksAuditVo;
import com.meisupic.copyright.domain.vo.WorksImageVo;
import com.meisupic.copyright.exception.BizException;
import com.meisupic.copyright.notify.NotifyQueue;
import com.meisupic.copyright.repo.CategoryRepo;
import com.meisupic.copyright.repo.CopyRightWorksRepo;
import com.meisupic.copyright.repo.CopyrightWorkAuditRecordRepo;
import com.meisupic.copyright.repo.GoodsRepo;
import com.meisupic.copyright.repo.RealNameAuthRepo;
import com.meisupic.copyright.repo.UsersRepo;
import com.meisupic.copyright.service.IAccountService;
import com.meisupic.copyright.service.ICopyRightWorksService;
import com.meisupic.copyright.service.IDeclarationFilesService;
import com.meisupic.copyright.service.IMessageService;
import com.meisupic.copyright.service.IOssService;
import com.meisupic.copyright.service.IRealNameAuthService;
import com.meisupic.copyright.service.ISalesService;
import com.meisupic.copyright.service.ITimevaleSignService;
import com.meisupic.copyright.service.VipMemberService;
import com.meisupic.copyright.support.HttpClient;
import com.meisupic.copyright.support.HttpRequester;
import com.meisupic.copyright.support.PdfToImage;
import com.meisupic.copyright.support.Response;
import com.meisupic.copyright.util.BeanMapper;
import com.meisupic.copyright.util.BeanUtil;
import com.meisupic.copyright.util.CategoryUtil;
import com.meisupic.copyright.util.DateUtil;
import com.meisupic.copyright.util.MD5Util;
import com.meisupic.copyright.util.StringUtil;
import com.yuanbenlian.common.InvalidException;
import com.yuanbenlian.model.Metadata;
import com.yuanbenlian.model.SecretKey;
import com.yuanbenlian.model.http.BlockHashQueryResp;
import com.yuanbenlian.model.http.BlockHashQueryResp.BlockHashResp;
import com.yuanbenlian.model.http.MetadataSaveResp;
import com.yuanbenlian.service.DTCPProcessor;
import com.yuanbenlian.service.NodeProcessor;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.imageio.ImageIO;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;
import sun.misc.BASE64Decoder;

/**
 * creation wuxun
 *
 * @version V1.0
 * @Description: TODO
 * @date 2018/1/19 21:33
 */
@Service
public class CopyRightWorksServiceImpl implements ICopyRightWorksService {

  @Autowired
  private IRealNameAuthService realNameAuthService;

  @Autowired
  ITimevaleSignService timevaleSignService;

  @Autowired
  private CopyRightWorksRepo copyRightWorksRepo;

  @Autowired
  private CopyrightWorkAuditRecordRepo recordRepo;

  @Autowired
  private CategoryRepo categoryRepo;

  @Autowired
  private UsersRepo usersRepo;

  @Autowired
  private RealNameAuthRepo realNameAuthRepo;

  @Autowired
  private CopyrightWorkAuditRecordRepo copyrightWorkAuditRecordRepo;

  @Autowired
  private IDeclarationFilesService declarationFilesService;

  @Autowired
  private IOssService ossService;

  @Autowired
  private IMessageService messageService;

  @Autowired
  private ISalesService salesService;

  @Autowired
  private IAccountService accountService;

  @Autowired
  private PdfToImage pdfToImage;

  @Autowired
  private NotifyQueue notifyQueue;

  @Autowired
  private GoodsRepo goodsRespo;

  @Autowired
  private VipMemberService vipMemberService;

  @Value("${esign.accountId}")
  private String accountId;

  @Value("${dci.server.url}")
  private String dciServerUrl;

  @Value("${oss.host}")
  private String ossHost;

  @Value("${yuanben.server.url}")
  private String ybServerUrl;

  @Value("${huaban.callback}")
  private String hbCallBackUrl;

  @Value("${rcode.server.url}")
  private String rCodeServerUrl;

  @Value("${client.callback.url}")
  private String clientCallbackUrl;

  @Value("${rcode.url}")
  private String rCodeRequestUrl;

  private String DECLARATION_FILE_PATH = OSS_HOST + Constants.DECLARATION_FILE_PATH;

  private static final String IMG_FORMAT = "jpg";

  private AtomicInteger errorCount = new AtomicInteger(0);

  private Logger logger = LoggerFactory.getLogger(this.getClass());

  /**
   * 保存版权登记信息.
   */
  @Override
  public List<CopyRightWorks> saveWorks(CopyRightWorksVo copyRightWorksVo, Long userId) {
    RealNameAuth realNameAuth = realNameAuthService.findByUserId(userId);
    if (realNameAuth == null) {
      throw new BizException("您还未进行实名认证！");
    }
    boolean isDisplay = copyRightWorksVo.getAuthorizeRule() != OfflineAuthorize;
    List<CopyRightWorks> worksList = convertCopyRightWorksVo2Po(copyRightWorksVo, realNameAuth);
    for (CopyRightWorks copyRightWorks : worksList) {
      copyRightWorks.setSubWorksType(copyRightWorksVo.getSubWorksType());
      copyRightWorks.setDisplay(isDisplay);
      copyRightWorks.setIsOnSale(0);
      copyRightWorksRepo.save(copyRightWorks);
    }
    return worksList;
  }

  @Override
  public void updateWorks(CopyRightWorks copyRightWorks) {
    copyRightWorksRepo.save(copyRightWorks);
  }

  /**
   * 根据ID查找copyrightWorks
   */
  @Override
  public CopyRightWorks findById(Long id) {
    return copyRightWorksRepo.findOne(id);
  }


  /**
   * 版权登记修改时查询修改数据
   */
  @Override
  public CopyRightWorksResponseVo findCopyRightWorksResponseVOById(Long id, boolean editFlag) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.getOne(id);
    Assert.notNull(copyRightWorks, "未找到登记数据");
    List<WorksImageVo> worksImageVoList = new ArrayList<>(16);
    List<CopyRightWorks> seriesCopyRightWorksList = new ArrayList<>(16);
    seriesCopyRightWorksList.add(copyRightWorks);
    if (copyRightWorks.getSeriesOfWorks()) {
      seriesCopyRightWorksList = copyRightWorksRepo
          .findBySeriesId(copyRightWorks.getSeriesId());
    }
    for (CopyRightWorks rightWorks : seriesCopyRightWorksList) {
      WorksImageVo worksImageVo = new WorksImageVo();
      worksImageVo.setId(rightWorks.getId());
      if (editFlag) {
        worksImageVo.setImageName(rightWorks.getImageName());
      } else {
        worksImageVo.setImageName(
            StringUtil.isEmpty(rightWorks.getHuabanThumbnailUrl()) ? rightWorks.getImageName()
                : rightWorks.getHuabanThumbnailUrl());
      }
      worksImageVo.setEpsImageName(rightWorks.getEpsImageName());
      worksImageVoList.add(worksImageVo);
    }

    CopyRightWorksResponseVo responseVO = BeanMapper
        .map(copyRightWorks, CopyRightWorksResponseVo.class);
    responseVO.setImagesName(worksImageVoList);
    return responseVO;
  }

  /**
   * 版权登记确认操作
   *
   * @return 返回登记的数量
   */
  @Override
  public List<String> confirmWorksInfo(Long id) {

    List<String> dnaList = new ArrayList<>();
    int reduceCount = 0;

    CopyRightWorks copyRightWorks = copyRightWorksRepo.getOne(id);
    Assert.notNull(copyRightWorks, "未找到登记数据");
    logger.info("正在确认id为{}的作品", id);
    if (!WorksProcessDetailEnum.commiting
        .equals(copyRightWorks.getWorksProcessDetail())) {
      throw new BizException("非待提交状态下不允许确认操作");
    }

    RealNameAuth realNameAuth = realNameAuthService.findByUserId(copyRightWorks.getCreatorId());
    String privateKey = realNameAuth.getPrivateKey();
    if (StringUtil.isEmpty(privateKey)) {
      SecretKey secretKey = GeneratorSecp256k1Key();
      realNameAuth.setPrivateKey(secretKey.getPrivateKey());
      realNameAuth.setPublicKey(secretKey.getPublicKey());
      realNameAuthRepo.save(realNameAuth);
    }
    realNameAuthService.registerUser(realNameAuth);
    Integer publishstatus = copyRightWorks.getPublishStatus();
    if (copyRightWorks.getSeriesOfWorks()) {
      List<CopyRightWorks> copyRightWorksList = copyRightWorksRepo
          .findBySeriesId(copyRightWorks.getSeriesId());
      for (CopyRightWorks rightWorks : copyRightWorksList) {
        sendRcodeApply(rightWorks);
        String dna = getWorksDna(rightWorks, realNameAuth.getPrivateKey());
        dnaList.add(dna);
        rightWorks.setDna(dna);
        rightWorks.setRCodeStatus(0);
        rightWorks.setWorksProcess(WorksProcessEnum.commited);
        rightWorks.setWorksProcessDetail(WorksProcessDetailEnum.commited);
        if (PUBLISH_STATUS_UNPUBLISHED == publishstatus) {
          rightWorks.setPublishStatus(PUBLISH_STATUS_PUBLISHED);
          rightWorks.setFirstPublishDate(new Date());
          rightWorks.setFirstPublishCountry("中国");
          rightWorks.setFirstPublishProvince("北京");
          rightWorks.setFirstPublishCity("北京");
        }
      }
      copyRightWorksRepo.save(copyRightWorksList);
      if (copyRightWorks.getAuthorizeRule() == OfflineAuthorize) {
        reduceCount = copyRightWorksList.size();
      }

    } else {
      if (PUBLISH_STATUS_UNPUBLISHED == publishstatus) {
        copyRightWorks.setPublishStatus(PUBLISH_STATUS_PUBLISHED);
        copyRightWorks.setFirstPublishDate(new Date());
        copyRightWorks.setFirstPublishProvince("北京");
        copyRightWorks.setFirstPublishCity("北京");
        copyRightWorks.setFirstPublishCountry("中国");
      }
      sendRcodeApply(copyRightWorks);
      String dna = getWorksDna(copyRightWorks, realNameAuth.getPrivateKey());
      dnaList.add(copyRightWorks.getRCode());
      copyRightWorks.setDna(dna);
      copyRightWorks.setWorksProcess(WorksProcessEnum.commited);
      copyRightWorks.setWorksProcessDetail(WorksProcessDetailEnum.commited);
      copyRightWorks.setRCodeStatus(0);
      copyRightWorksRepo.save(copyRightWorks);
      if (copyRightWorks.getAuthorizeRule() == OfflineAuthorize) {
        reduceCount = 1;
      }
    }
    sendMessageRegSucc(copyRightWorks.getWorksFullName(), id, copyRightWorks.getCreatorId());
    long userId = copyRightWorks.getCreatorId();
    Long user_id = usersRepo.findOne(userId).getHuabanUserId();
    if (!StringUtil.isEmpty(user_id) && user_id != 0) {
      hbNotify(0, user_id, copyRightWorks.getHuabanImageUrl(), copyRightWorks.getImageName(), null,
          null, null, copyRightWorks.getId());
    }
    if (reduceCount > 0) {
      vipMemberService.reduceCount(userId, reduceCount);
    }
    return dnaList;
  }

  /**
   * DCI回调处理方法
   */
  @Override
  public ReturnToDciMessageVo receiveDciCertificate(String callbackMessage) {

    if (StringUtil.isEmpty(callbackMessage)) {
      logger.info("DCI返回的数据为空");
      return ReturnToDciMessageVo.failure("DCI返回的数据为空");
    }

    DciCallbackMessageVo dcicbMsgVo = JSON
        .parseObject(callbackMessage, DciCallbackMessageVo.class);
    String resId = dcicbMsgVo.getRegisterId();
    if (StringUtil.isEmpty(resId)) {
      logger.error("resId为空");
      return ReturnToDciMessageVo.failure("");
    }
    List<CopyRightWorks> copyRightWorksList = copyRightWorksRepo.findByResId(resId);
    if (StringUtil.isEmpty(copyRightWorksList)) {
      logger.error("未找到resId为{}的数据", resId);
      return ReturnToDciMessageVo.failure("");
    }
    CopyRightWorks updateEntity = copyRightWorksList.get(0);
    boolean flag = dcicbMsgVo.isFlag();
    if (flag) {
      saveAndUploadCertToOss(dcicbMsgVo.getFileName(), dcicbMsgVo.getContent());

      CopyrightWorksAuditRecord record = new CopyrightWorksAuditRecord(updateEntity.getId(), "版保中心",
          1, "通过");
      recordRepo.save(record);

      updateEntity.setWorksProcess(WorksProcessEnum.passed);
      updateEntity.setWorksProcessDetail(WorksProcessDetailEnum.cpccpassed);
      updateEntity.setDciCode(dcicbMsgVo.getDciCode());
      updateEntity.setDciUrl(dcicbMsgVo.getUrl());
      updateEntity.setPromulgateDate(new Date());
      updateEntity.setCertFileName(dcicbMsgVo.getFileName());
      copyRightWorksRepo.save(updateEntity);

      sendMessagePassed(updateEntity.getWorksFullName(), updateEntity.getId(),
          updateEntity.getCreatorId(), updateEntity.getDciCode());
      if (AuthorizeRuleEnum.SeniorPartnerAuthorize != updateEntity.getAuthorizeRule()) {
        sendSmsPassed(updateEntity.getWorksFullName(), updateEntity.getCreatorId());
      }

      long userId = updateEntity.getCreatorId();
      Long user_id = usersRepo.findOne(userId).getHuabanUserId();
      String certUrl =
          "http://meisudci.oss-cn-beijing.aliyuncs.com/certificate/" + dcicbMsgVo.getFileName();
      if (!StringUtil.isEmpty(user_id) && user_id != 0) {

        hbNotify(1, user_id, updateEntity.getHuabanImageUrl(), updateEntity.getImageName(), null,
            dcicbMsgVo.getDciCode(), certUrl, updateEntity.getId());
      }

      RealNameAuth realNameAuth = realNameAuthService.findByUserId(userId);
      if (StringUtils.isNotEmpty(realNameAuth.getClientId())) {
        clientNotify(true, dcicbMsgVo.getUrl(), "", dcicbMsgVo.getDciCode(), certUrl,
            updateEntity.getId());
      }

    } else {
      String reason = dcicbMsgVo.getAuditDesc();
      updateEntity.setWorksProcess(WorksProcessEnum.refused);
      updateEntity.setWorksProcessDetail(WorksProcessDetailEnum.cpccrefused);
      copyRightWorksRepo.save(updateEntity);
      CopyrightWorksAuditRecord record = new CopyrightWorksAuditRecord(updateEntity.getId(), "版保中心",
          0, reason);
      recordRepo.save(record);
      sendMessageRejected(updateEntity.getWorksFullName(), updateEntity.getId(),
          updateEntity.getCreatorId());
      if (AuthorizeRuleEnum.SeniorPartnerAuthorize != updateEntity.getAuthorizeRule()) {
        sendSmsRejected(updateEntity.getWorksFullName(), updateEntity.getCreatorId());
      }

      long userId = updateEntity.getCreatorId();
      Long user_id = usersRepo.findOne(userId).getHuabanUserId();
      if (!StringUtil.isEmpty(user_id) && user_id != 0) {
        hbNotify(0, user_id, updateEntity.getHuabanImageUrl(), updateEntity.getImageName(), reason,
            null, null, updateEntity.getId());
      }

      RealNameAuth realNameAuth = realNameAuthService.findByUserId(userId);
      if (StringUtils.isNotEmpty(realNameAuth.getClientId())) {
        clientNotify(false, null, reason, null, null,
            updateEntity.getId());
      }
    }

    return ReturnToDciMessageVo.success();
  }

  @Cacheable(value = "categoryCache")
  @Override
  public List<CategroyVo> findCategoryVoList() {
    Sort sort = new Sort(Sort.Direction.DESC, "sortOrder");
    List<Category> categoryList = categoryRepo.findByParentId(3, sort);
    List<CategroyVo> categroyVoList = BeanMapper.mapList(categoryList, CategroyVo.class);
    return categroyVoList;
  }

  @Override
  public Page<CopyRightWorksRowVo> findPageCopyRightWorkRowVO(WorksQuery worksQuery,
      Pageable pageable) {
    Specification<CopyRightWorks> specification = createSpecification(worksQuery);
    Page<CopyRightWorks> copyRightWorksPage = copyRightWorksRepo.findAll(specification, pageable);
    List<CopyRightWorks> copyRightWorksList = copyRightWorksPage.getContent();
    List<CopyRightWorksRowVo> worksVoList = BeanMapper
        .mapList(copyRightWorksList, CopyRightWorksRowVo.class);
    Page<CopyRightWorksRowVo> worksVoPage = new PageImpl<>(worksVoList, pageable,
        copyRightWorksPage.getTotalElements());
    return worksVoPage;
  }

  @Override
  public CopyRightWorksRowVo findSingleWorksVo(Long id) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.findOne(id);
    RealNameAuth realNameAuth = realNameAuthService.findByUserId(copyRightWorks.getCreatorId());
    CopyRightWorksRowVo copyRightWorksRowVo = BeanMapper
        .map(copyRightWorks, CopyRightWorksRowVo.class);
    copyRightWorksRowVo.setMobile(realNameAuth.getMobile());
    List<CopyrightWorksAuditRecord> copyrightWorksAuditRecords = copyrightWorkAuditRecordRepo
        .findTop1ByCopyrightWorksIdIsAndProcessResultIsOrderByCreateTimeDesc(
            id, 0);
    if (!StringUtil.isEmpty(copyrightWorksAuditRecords)) {
      copyRightWorksRowVo.setFailReason(copyrightWorksAuditRecords.get(0).getProcessComment());
    }
    return copyRightWorksRowVo;
  }

  @Override
  public CopyRightWorksRowVo findSingleWorksVoByGoodsId(Long goodsId) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.findCopyRightWorksByGoodsIdEquals(goodsId);
    RealNameAuth realNameAuth = realNameAuthService.findByUserId(copyRightWorks.getCreatorId());
    CopyRightWorksRowVo copyRightWorksRowVo = BeanMapper
        .map(copyRightWorks, CopyRightWorksRowVo.class);
    copyRightWorksRowVo.setMobile(realNameAuth.getMobile());
    return copyRightWorksRowVo;
  }

  /**
   * 删除作品
   */
  @Override
  public void deleteWorks(Long id) {
    CopyRightWorks works = copyRightWorksRepo.findOne(id);
    if (!StringUtil.isEmpty(works)) {
      if (WorksProcessEnum.commiting != works.getWorksProcess() && WorksProcessEnum.refused != works
          .getWorksProcess()) {
        throw new BizException("该状态不允许删除");
      }
    }
    copyRightWorksRepo.delete(id);
  }

  /**
   * 作品审核通过时的处理方法
   */
  public void doPass(WorksAuditVo worksAuditVo) {

    if (errorCount.get() > 2) {
      throw new BizException("今日出错已达3次，请检查后重试！");
    }

    CopyRightWorks copyRightWorks = copyRightWorksRepo.findOne(worksAuditVo.getId());
    RealNameAuth realNameAuth = realNameAuthService.findByUserId(copyRightWorks.getCreatorId());
    Assert.notNull(copyRightWorks, "未找到登记数据");
    if (copyRightWorks != null && WorksProcessDetailEnum.commited != copyRightWorks
        .getWorksProcessDetail() && WorksProcessDetailEnum.preCpcc != copyRightWorks
        .getWorksProcessDetail()) {
      throw new BizException("状态错误，非待平台审核状态");
    }

    //判断申请人是否已推送
    analyzingApplyPushed(realNameAuth);

    copyRightWorks.setResId(StringUtil.get32UUID());
    copyRightWorks.setWorksProcess(WorksProcessEnum.commited);
    copyRightWorks.setWorksProcessDetail(WorksProcessDetailEnum.mspassed);
    if (!StringUtil.isEmpty(worksAuditVo.getKeywords())) {
      copyRightWorks.setKeywords(copyRightWorks.getKeywords() + "," + worksAuditVo.getKeywords());
    }
    if (!StringUtil.isEmpty(worksAuditVo.getScore())) {
      copyRightWorks.setScore(worksAuditVo.getScore());
    }
    if (!StringUtil.isEmpty(worksAuditVo.getUses())) {
      copyRightWorks.setUses(worksAuditVo.getUses());
    }

    String worksJsonData = getWorksJsonData(copyRightWorks, realNameAuth);
    String proxySignResult = timevaleSignService.localTextSign(worksJsonData);
    String applyerSignResult = timevaleSignService
        .localTextSign(realNameAuth.getAccountId(), worksJsonData);
    Map<String, String> params = new HashMap<>();
    params.put("json", worksJsonData);
    params.put("proxySign", proxySignResult);
    params.put("applyerSign", applyerSignResult);
    params.put("eCertId", accountId);
    String url = dciServerUrl + "/textregisterforesign.do";
    Integer flag = 0;
    String message = "";

    try {
      Response response = HttpRequester.sendPost(url, params);
      logger.info("DCI返回结果" + response.getContent());
      if (response.getStatusCode() == 200) {
        String content = response.getContent();
        if (StringUtil.isEmpty(content) || "null".equals(content)) {
          errorCount.incrementAndGet();
        }
        JSONObject json = JSON.parseObject(content);
        flag = json.getInteger("flag");
        message = json.getString("message");
      } else {
        throw new BizException("版权中心接口连接异常");
      }
    } catch (Exception e) {
      logger.error("DCI登记接口异常", e);
      throw new BizException("DCI登记接口异常");
    }
    if (flag == 2) {
      copyRightWorksRepo.save(copyRightWorks);

      CopyrightWorksAuditRecord record = new CopyrightWorksAuditRecord(worksAuditVo.getId(),
          worksAuditVo.getAuditor(), 1, worksAuditVo.getRefuseReason());
      copyrightWorkAuditRecordRepo.save(record);
    } else if (flag == 1) {
      errorCount.incrementAndGet();
      logger.info(worksJsonData);
      logger.info(proxySignResult);
      logger.info(applyerSignResult);
      throw new BizException(message);
    }

  }


  /**
   * 作品审核通过时的处理方法
   */
  public void sendRcodeApply(CopyRightWorks copyRightWorks) {
    Response response = HttpClient.get(rCodeRequestUrl+"?id="+copyRightWorks.getId(), null);
    logger.info("请求rCode:{}", JSON.toJSONString(response));
  }

  /**
   * 作品审核不通过时执行的方法
   */
  public void doRefuse(WorksAuditVo worksAuditVo) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.findOne(worksAuditVo.getId());
    if (copyRightWorks != null && WorksProcessDetailEnum.commited != copyRightWorks
        .getWorksProcessDetail()) {
      throw new BizException("状态错误，非待平台审核状态");
    }
    copyRightWorks.setWorksProcess(WorksProcessEnum.refused);
    copyRightWorks.setWorksProcessDetail(WorksProcessDetailEnum.msrefused);
    copyRightWorksRepo.save(copyRightWorks);

    CopyrightWorksAuditRecord record = new CopyrightWorksAuditRecord(worksAuditVo.getId(),
        worksAuditVo.getAuditor(), 0, worksAuditVo.getRefuseReason());
    copyrightWorkAuditRecordRepo.save(record);

    sendMessageRejected(copyRightWorks.getWorksFullName(), copyRightWorks.getId(),
        copyRightWorks.getCreatorId());
    if (AuthorizeRuleEnum.SeniorPartnerAuthorize != copyRightWorks.getAuthorizeRule()) {
      sendSmsRejected(copyRightWorks.getWorksFullName(), copyRightWorks.getCreatorId());
    }

    long userId = copyRightWorks.getCreatorId();
    Long user_id = usersRepo.findOne(userId).getHuabanUserId();
    if (user_id == null || user_id == 0) {
      return;
    }
    hbNotify(-1, user_id, copyRightWorks.getHuabanImageUrl(), copyRightWorks.getImageName(),
        worksAuditVo.getRefuseReason(), null, null, copyRightWorks.getId());

    RealNameAuth realNameAuth = realNameAuthService.findByUserId(userId);
    if (StringUtils.isNotEmpty(realNameAuth.getClientId())) {
      clientNotify(false, null, worksAuditVo.getRefuseReason(), null, null,
          copyRightWorks.getId());
    }

  }

  @Override
  public int countCommitedWorks(Long userId) {
    List<CopyRightWorks> worksList = copyRightWorksRepo
        .findCopyRightWorksByCreatorIdAndWorksProcess(userId, WorksProcessEnum.commited);
    return worksList.size();
  }

  @Override
  public List<CopyRightWorksRowVo> findLatestWorks(Long userid) {
    List<CopyRightWorks> copyRightWorksList = copyRightWorksRepo
        .findTop6ByCreatorIdOrderByCreateTimeDesc(userid);
    List<CopyRightWorksRowVo> worksRowVos = BeanMapper
        .mapList(copyRightWorksList, CopyRightWorksRowVo.class);
    return worksRowVos;
  }

  @Override
  public void updateScore(Long id, Integer score) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.findOne(id);
    if (!StringUtil.isEmpty(copyRightWorks)) {
      copyRightWorks.setScore(score);
      copyRightWorksRepo.save(copyRightWorks);
    }
  }

  @Override
  public void updateScore(Long id, String keyWords) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.findOne(id);
    if (!StringUtil.isEmpty(copyRightWorks)) {
      copyRightWorks.setKeywords(keyWords);
      copyRightWorksRepo.save(copyRightWorks);
    }
  }

  @Override
  public void updateWorksType(Long id, String worksType) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.findOne(id);
    if (!StringUtil.isEmpty(copyRightWorks)) {
      copyRightWorks.setWorksType(worksType);
      copyRightWorksRepo.save(copyRightWorks);
    }
  }

  @Override
  public String getGoodsSn(Long worksId) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.findOne(worksId);
    Long goodsId = copyRightWorks.getGoodsId();
    if (goodsId == null || goodsId == 0) {
      return "";
    }
    Goods goods = goodsRespo.findOne(goodsId);
    if (goods == null) {
      return "";
    }
    return goods.getGoodsSn();
  }

  /**
   * 判断作品名称是否重复
   */
  @Override
  public boolean isRepeatedWorksName(Long id, String worksName) {
    CopyRightWorks copyRightWorks;
    if (id != null) {
      copyRightWorks = copyRightWorksRepo
          .findCopyRightWorksByWorksFullNameIsAndIdNot(worksName, id);
    } else {
      copyRightWorks = copyRightWorksRepo.findCopyRightWorksByWorksFullNameIs(worksName);
    }

    return copyRightWorks == null;
  }

  @Override
  public boolean resetErrorCount() {
    errorCount.set(0);
    return errorCount.get() == 0;
  }

  @Override
  public void offImage(Long id) {
    CopyRightWorks copyRightWorks = copyRightWorksRepo.findOne(id);
    if (!StringUtil.isEmpty(copyRightWorks)) {
      copyRightWorks.setIsOnSale(0);
      copyRightWorksRepo.save(copyRightWorks);
      Long goodsId = copyRightWorks.getGoodsId();
      if (goodsId != null) {
        Goods goods = goodsRespo.findOne(goodsId);
        if (goods != null) {
          goods.setIsOnSale((byte) 0);
          goodsRespo.save(goods);
        }
      }
    }


  }


  protected List<CopyRightWorks> convertCopyRightWorksVo2Po(CopyRightWorksVo copyRightWorksVo,
      RealNameAuth realNameAuth) {
    List<CopyRightWorks> copyRightWorksList = new ArrayList<>(16);
    List<WorksImageVo> worksImageVoList = copyRightWorksVo.getImagesName();
    int workFullNameIndex = 1;
    String seriesId = StringUtil.get32UUID();
    for (WorksImageVo worksImageVo : worksImageVoList) {
      CopyRightWorks copyRightWorks = BeanMapper.map(copyRightWorksVo, CopyRightWorks.class);
      copyRightWorks.setId(worksImageVo.getId());
      if (worksImageVoList.size() > 1) {
        copyRightWorks.setWorksFullName(copyRightWorksVo.getWorksFullName() + workFullNameIndex);
        copyRightWorks.setSeriesOfWorks(true);
        copyRightWorks.setSeriesId(seriesId);
      }
      copyRightWorks.setImageName(worksImageVo.getImageName());
      copyRightWorks.setEpsImageName(worksImageVo.getEpsImageName());
      if (!StringUtil.isEmpty(worksImageVo.getHuabanImageUrl())) {
        copyRightWorks.setHuabanImageUrl(worksImageVo.getHuabanImageUrl());
        copyRightWorks.setHuabanThumbnailUrl(worksImageVo.getHuabanThumbnailUrl());
        String hubanImageUrl = worksImageVo.getHuabanImageUrl();
        String key = WORKS_DIR + "/" + StringUtil.get32UUID();
        copyRightWorks.setImageName(OSS_HOST + key);
        new Thread(() -> {
          try {
            ossService.putObject(key, IOUtils.toByteArray(new URL(hubanImageUrl)));
          } catch (IOException e) {
            logger.error("读取图片失败", e);
          }

        }).start();
      }
      //版权登记的默认信息
      copyRightWorks.setAuthor(realNameAuth.getAuthName());
      String statementSuffix = StringUtil.get32UUID();
      if (AUTH_TYPE_PERSON.equals(realNameAuth.getAuthType())) {
        copyRightWorks.setRightOwnMode(RIGHT_OWN_MODE_PERSONAL_WORKS);
      } else {
        copyRightWorks.setLegalCreationStatement(statementSuffix + "_3.pdf");
        copyRightWorks.setRightOwnMode(RIGHT_OWN_MODE_LEGAL_WORKS);
      }
      copyRightWorks.setRightFetchMode(RIGHT_FETCH_MODE_ORIGINAL_ACQUISITION);
      copyRightWorks.setApplyType(APPLY_TYPE_AGENT);
      copyRightWorks.setCreativeNature(CREATIVENATURE_ORIGINAL);
      copyRightWorks.setCommitment(COMMITMENT);
      copyRightWorks.setCreatorId(realNameAuth.getCreatorId());
      copyRightWorks.setApplicantAccountId(realNameAuth.getAccountId());
      copyRightWorks.setOriginalStatement(statementSuffix + "_1.pdf");
      copyRightWorks.setCreativeStatement(statementSuffix + "_2.pdf");
      copyRightWorks.setWorksProcess(WorksProcessEnum.commiting);
      copyRightWorks.setWorksProcessDetail(WorksProcessDetailEnum.commiting);
      if (NonExclusiveAuthorize.name().equals(copyRightWorks.getAuthorizeRule().name())) {
        copyRightWorks.setSplitPercentage(new BigDecimal(0.5));
      } else if (ExclusiveAuthorize.name().equals(copyRightWorks.getAuthorizeRule().name())) {
        copyRightWorks.setSplitPercentage(new BigDecimal(0.7));
      }
      copyRightWorks.setCreatorId(realNameAuth.getCreatorId());
      copyRightWorks.setCreateor(realNameAuth.getAuthName());
      if (!StringUtil.isEmpty(copyRightWorks.getId())) {
        CopyRightWorks copyRightWorksExistEnity = copyRightWorksRepo
            .findOne(copyRightWorks.getId());
        if (WorksProcessEnum.commited.name()
            .equals(copyRightWorksExistEnity.getWorksProcess().name())) {
          logger.info("提交审核中的作品id{}", copyRightWorksExistEnity.getId());
          throw new BizException("审核中状态下不允许提交");
        } else if (WorksProcessEnum.passed.name()
            .equals(copyRightWorksExistEnity.getWorksProcess().name())) {
          logger.info("提交已通过的作品id{}", copyRightWorksExistEnity.getId());
          throw new BizException("已通过的作品不允许提交");
        }
        BeanUtil.copyPropertiesIgnoreNull(copyRightWorks, copyRightWorksExistEnity);
        copyRightWorksExistEnity
            .setOriginalStatement(DECLARATION_FILE_PATH + copyRightWorks.getOriginalStatement());
        copyRightWorksExistEnity
            .setCreativeStatement(DECLARATION_FILE_PATH + copyRightWorks.getCreativeStatement());
        if (copyRightWorks.getLegalCreationStatement() != null) {
          copyRightWorksExistEnity.setLegalCreationStatement(
              DECLARATION_FILE_PATH + copyRightWorks.getLegalCreationStatement());
        }
        copyRightWorksList.add(copyRightWorksExistEnity);
      } else {
        copyRightWorks.setKeywords("");
        copyRightWorksList.add(copyRightWorks);
      }
      declarationFilesService.generateFiles(copyRightWorks, copyRightWorksVo.getCreativePurpose());
      //声明文件重新赋值完整路径
      copyRightWorks
          .setOriginalStatement(DECLARATION_FILE_PATH + copyRightWorks.getOriginalStatement());
      copyRightWorks
          .setCreativeStatement(DECLARATION_FILE_PATH + copyRightWorks.getCreativeStatement());

      if (copyRightWorks.getLegalCreationStatement() != null) {
        copyRightWorks.setLegalCreationStatement(
            DECLARATION_FILE_PATH + copyRightWorks.getLegalCreationStatement());
      }

      workFullNameIndex++;
    }
    return copyRightWorksList;
  }

  /**
   * 生成证书文件并上传到oss
   */
  public void saveAndUploadCertToOss(String fileName, String base64Content) {
    String imageName = fileName.substring(0, fileName.indexOf('.') + 1) + IMG_FORMAT;
    File certFile = new File("/root/dci/", fileName);
    File imgDestFile = new File(FileUtils.getUserDirectoryPath(), imageName);
    try {
      byte[] buffer = new BASE64Decoder().decodeBuffer(base64Content);
      FileUtils.writeByteArrayToFile(certFile, buffer);
      ossService.putObject(CERTIFICATE_FILE_PATH + fileName, certFile);

      pdfToImage.pdfToImage(certFile, imgDestFile, IMG_FORMAT, 96f, false);
      ossService.putObject(CERTIFICATE_FILE_PATH + imageName, imgDestFile);
      FileUtils.forceDelete(certFile);
      FileUtils.forceDelete(imgDestFile);
    } catch (IOException e) {
      logger.error("生成证书文件失败", e);
      throw new BizException("生成证书文件失败");
    }
  }

  @Override
  public String updateRCodeStatus(RCodeUpdateBo rCodeUpdateBo) {
    RCodeReplyBo rCodeReplyBo = new RCodeReplyBo();
    try {
      CopyRightWorks copyRightWorks = copyRightWorksRepo.findCopyRightWorksByRCodeIs(rCodeUpdateBo.getDcir());
      if(copyRightWorks==null){
        rCodeReplyBo.setFlag(false);
        rCodeReplyBo.setMessage("未找到登记信息");
      }else{
        copyRightWorks.setRCodeStatus(Integer.valueOf(rCodeUpdateBo.getStatus()));
        copyRightWorksRepo.save(copyRightWorks);
        rCodeReplyBo.setFlag(true);
      }
    }catch (IncorrectResultSizeDataAccessException exception){
      rCodeReplyBo.setFlag(false);
      rCodeReplyBo.setMessage("找到多条登记信息");
    }
    return JSON.toJSONString(rCodeReplyBo);
  }

  private Specification<CopyRightWorks> createSpecification(WorksQuery query) {
    return new Specification<CopyRightWorks>() {
      @Override
      public Predicate toPredicate(Root<CopyRightWorks> root, CriteriaQuery<?> criteriaQuery,
          CriteriaBuilder criteriaBuilder) {
        List<Predicate> predicates = new ArrayList<>();
        if (!StringUtil.isEmpty(query.getWorksNameOrDciCode())) {
          Predicate predicate1 = criteriaBuilder
              .like(root.get("worksFullName"), "%" + query.getWorksNameOrDciCode() + "%");
          Predicate predicate2 = criteriaBuilder
              .like(root.get("dciCode"), "%" + query.getWorksNameOrDciCode() + "%");
          predicates.add(criteriaBuilder.or(predicate1, predicate2));
        }

        if (!StringUtil.isEmpty(query.getCategoryId())) {
          predicates.add(criteriaBuilder.equal(root.get("categoryId"), query.getCategoryId()));
        }

        if (!StringUtil.isEmpty(query.getCreateor())) {
          predicates
              .add(criteriaBuilder.like(root.get("createor"), "%" + query.getCreateor() + "%"));
        }

        if (!StringUtil.isEmpty(query.getStartDate())) {
          predicates.add(criteriaBuilder
              .between(root.get("createTime"), query.getStartDate(), query.getEndDate()));
        }

        if (!StringUtil.isEmpty(query.getWorksProcessDetail())) {
          predicates.add(
              criteriaBuilder.equal(root.get("worksProcessDetail"), query.getWorksProcessDetail()));
        }

        if (!StringUtil.isEmpty(query.getWorksProcess())) {
          predicates.add(criteriaBuilder.equal(root.get("worksProcess"), query.getWorksProcess()));
        }

        if (!StringUtil.isEmpty(query.getCreatorId())) {
          predicates.add(criteriaBuilder.equal(root.get("creatorId"), query.getCreatorId()));
        }

        if (query.getIsAdmin() != null && query.getIsAdmin()) {
          if (StringUtil.isEmpty(query.getAuthorizeRule())) {
            predicates
                .add(criteriaBuilder
                    .notEqual(root.get("authorizeRule"), AuthorizeRuleEnum.SeniorPartnerAuthorize));
          } else {
            predicates
                .add(criteriaBuilder.equal(root.get("authorizeRule"), query.getAuthorizeRule()));
          }
        }

        return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
      }
    };
  }

  private String getWorksJsonData(CopyRightWorks copyRightWorks, RealNameAuth realNameAuth) {
    DCIWorksRegisterBo dciWorksRegisterBo = BeanMapper
        .map(copyRightWorks, DCIWorksRegisterBo.class);
    dciWorksRegisterBo
        .setCompletedate(DateUtil.format(copyRightWorks.getCreationDate(), "yyyy/MM/dd HH:mm:ss"));
    dciWorksRegisterBo.setFirstpublishdate(
        DateUtil.format(copyRightWorks.getFirstPublishDate(), "yyyy/MM/dd HH:mm:ss"));
    dciWorksRegisterBo.setProxycontent("代理进行作品版权登记");
    dciWorksRegisterBo.setApplyer(getApplyer(realNameAuth));
    dciWorksRegisterBo.setProxy(getProxy());
    dciWorksRegisterBo.setProductauthor(getProductauthor(realNameAuth));
    dciWorksRegisterBo.setAttachment(getAttachments(copyRightWorks, realNameAuth));
    return JSON.toJSONString(dciWorksRegisterBo);
  }

  private String getRcodeJsonData(CopyRightWorks copyRightWorks, RealNameAuth realNameAuth) {
    RCodeRegisterBo rCodeRegisterBo = new RCodeRegisterBo();

    rCodeRegisterBo.setTextfullname(copyRightWorks.getWorksFullName());
    rCodeRegisterBo.setApplytype(copyRightWorks.getApplyType());
    rCodeRegisterBo.setAuthorrealname(copyRightWorks.getAuthor());
    rCodeRegisterBo.setAuthorwritename(copyRightWorks.getAuthor());
    rCodeRegisterBo.setCompletecity(copyRightWorks.getCreationCity());
    rCodeRegisterBo.setCompletecountry(copyRightWorks.getCreationCountry());
    rCodeRegisterBo.setObtainmode(String.valueOf(copyRightWorks.getRightFetchMode()));
    rCodeRegisterBo.setPublishstatus(copyRightWorks.getPublishStatus());
    rCodeRegisterBo.setFirstpublishcity(copyRightWorks.getFirstPublishCity());
    rCodeRegisterBo.setFirstpublishcountry(copyRightWorks.getFirstPublishCountry());
    rCodeRegisterBo.setRightownmode(String.valueOf(copyRightWorks.getRightOwnMode()));
    rCodeRegisterBo.setResid(copyRightWorks.getResId());
    rCodeRegisterBo.setRegistertype(copyRightWorks.getWorksType());
    rCodeRegisterBo
        .setCompletedate(DateUtil.format(copyRightWorks.getCreationDate(), "yyyy/MM/dd HH:mm:ss"));
    rCodeRegisterBo.setFirstpublishdate(
        DateUtil.format(copyRightWorks.getFirstPublishDate(), "yyyy/MM/dd HH:mm:ss"));
    rCodeRegisterBo.setProxycontent("代理进行作品版权登记");
    rCodeRegisterBo.setApplyer(getApplyer(realNameAuth));
    rCodeRegisterBo.setProxy(getProxy());
    rCodeRegisterBo.setProductauthor(getProductauthor(realNameAuth));
    rCodeRegisterBo.setAttachment(getRCodeAttachments(copyRightWorks, realNameAuth));
    rCodeRegisterBo.setApplyplatform("282");
    rCodeRegisterBo.setProducthash(getProductHash(copyRightWorks, realNameAuth));

    return JSON.toJSONString(rCodeRegisterBo);
  }

  private String getProductHash(CopyRightWorks copyRightWorks, RealNameAuth realNameAuth) {
    try {
      String base64Name = Base64Utils.encodeToString(realNameAuth.getAuthName().getBytes("UTF-8"));
      String base64IdCardType = Base64Utils
          .encodeToString(realNameAuth.getDocumentType().toString().getBytes("UTF-8"));
      String metaDataHash = MD5Util
          .encode(base64Name + base64IdCardType + realNameAuth.getDocumetNo());

      String dataHash = DigestUtils
          .md5Hex(IOUtils.toByteArray(new URL(copyRightWorks.getImageName())));

      String fingerPrint = MD5Util.encode(metaDataHash + dataHash);
      return fingerPrint;
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (MalformedURLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

    return null;


  }


  private Applyer getApplyer(RealNameAuth realNameAuth) {
    Applyer applyer = new Applyer();
    applyer.setCaid(realNameAuth.getAccountId());
    return applyer;
  }

  private Proxy getProxy() {
    Proxy proxy = new Proxy();
    proxy.setCaid(accountId);
    return proxy;
  }

  /**
   * 著作权人信息
   */
  private List<Productauthor> getProductauthor(RealNameAuth realNameAuth) {
    List<Productauthor> productauthors = new ArrayList<>();
    Productauthor productauthor = new Productauthor();
    productauthor.setCountry("中国");
    productauthor.setProvince(realNameAuth.getProvince());
    productauthor.setCity(realNameAuth.getCity());
    productauthor.setName(realNameAuth.getAuthName());
    productauthor.setIdcardtype(realNameAuth.getDocumentType());
    productauthor.setIdnumber(realNameAuth.getDocumetNo());
    if (Constants.AUTH_TYPE_PERSON.equals(realNameAuth.getAuthType())) {
      productauthor.setPeopletype("1");
    } else {
      productauthor.setPeopletype("2");
    }
    productauthor.setCompanytype(3);
    productauthors.add(productauthor);
    return productauthors;
  }

  private List<Attachment> getAttachments(CopyRightWorks copyRightWorks,
      RealNameAuth realNameAuth) {
    try {
      List<Attachment> attachments = new ArrayList<>();
      Attachment zpyp = new Attachment();
      ImageInfo imageInfo = getImageInfo(copyRightWorks.getImageName());
      String styleProcess = "?x-oss-process=style/large_style_h_no_water";
      if (imageInfo.getImageHeight() > imageInfo.getImageWidth()) {
        styleProcess = "?x-oss-process=style/large_style_w_no_water";
      }
      String imageUrl = copyRightWorks.getImageName() + styleProcess;

      String zpypBase64Content = Base64Utils.encodeToString(IOUtils.toByteArray(new URL(imageUrl)));
      zpyp.setName("ZPYP-01.jpg");
      zpyp.setContent(zpypBase64Content);
      attachments.add(zpyp);

      //作品创作说明书
      Attachment QLGS07 = new Attachment();
      QLGS07.setName("QLGS-07.pdf");
      String qlgs07Base64Content = Base64Utils
          .encodeToString(IOUtils.toByteArray(new URL(copyRightWorks.getCreativeStatement())));
      QLGS07.setContent(qlgs07Base64Content);
      attachments.add(QLGS07);

      //身份证正面
      Attachment sfzzm = new Attachment();
      sfzzm.setName("SFZZM.jpg");
      String sfzzmBase64Content = Base64Utils
          .encodeToString(IOUtils.toByteArray(new URL(realNameAuth.getDocumentImgPositive())));
      sfzzm.setContent(sfzzmBase64Content);
      attachments.add(sfzzm);

      if (RIGHT_OWN_MODE_PERSONAL_WORKS == copyRightWorks.getRightOwnMode()) {
        //原创声明书
        Attachment QLGS01 = new Attachment();
        QLGS01.setName("QLGS-01.pdf");
        ;
        String qlgs01Base64Content = Base64Utils
            .encodeToString(IOUtils.toByteArray(new URL(copyRightWorks.getOriginalStatement())));
        QLGS01.setContent(qlgs01Base64Content);
        attachments.add(QLGS01);
        //身份证反面
        Attachment sfzfm = new Attachment();
        sfzfm.setName("SFZFM.jpg");
        String sfzfmBase64Content = Base64Utils
            .encodeToString(IOUtils.toByteArray(new URL(realNameAuth.getDocumentImgBack())));
        sfzfm.setContent(sfzfmBase64Content);
        attachments.add(sfzfm);

      } else {
        //法人作品品证明
        Attachment QLGS0804 = new Attachment();
        QLGS0804.setName("QLGS-0804.pdf");
        String qlgs0804Base64Content = Base64Utils
            .encodeToString(
                IOUtils.toByteArray(new URL(copyRightWorks.getLegalCreationStatement())));
        QLGS0804.setContent(qlgs0804Base64Content);
        attachments.add(QLGS0804);

        //证件反面
        Attachment sfzfm = new Attachment();
        sfzfm.setName("SFZFM.jpg");
        sfzfm.setContent(sfzzmBase64Content);
        attachments.add(sfzfm);
      }

      return attachments;
    } catch (IOException e) {
      logger.error("获取附件信息错误", e);
      throw new BizException("获取附件信息错误");
    }
  }

  private List<Attachment> getRCodeAttachments(CopyRightWorks copyRightWorks,
      RealNameAuth realNameAuth) {
    try {
      List<Attachment> attachments = new ArrayList<>();
      Attachment zpyp = new Attachment();
      ImageInfo imageInfo = getImageInfo(copyRightWorks.getImageName());
      String styleProcess = "?x-oss-process=style/large_style_h_no_water";
      if (imageInfo.getImageHeight() > imageInfo.getImageWidth()) {
        styleProcess = "?x-oss-process=style/large_style_w_no_water";
      }
      String imageUrl = copyRightWorks.getImageName() + styleProcess;

      String zpypBase64Content = Base64Utils.encodeToString(imageUrl.getBytes("utf-8"));
      zpyp.setName("ZPYP-01.jpg");
      zpyp.setContent(zpypBase64Content);
      zpyp.setSigndata(DigestUtils.sha256Hex(IOUtils.toByteArray(new URL(imageUrl))));
      attachments.add(zpyp);
      //作品创作说明书
      Attachment QLGS07 = new Attachment();
      QLGS07.setName("QLGS-07.pdf");
      String qlgs07Base64Content = Base64Utils
          .encodeToString(copyRightWorks.getCreativeStatement().getBytes("utf-8"));
      QLGS07.setContent(qlgs07Base64Content);
      QLGS07.setSigndata(DigestUtils
          .sha256Hex(IOUtils.toByteArray(new URL(copyRightWorks.getCreativeStatement()))));
      attachments.add(QLGS07);

      //身份证正面
      Attachment sfzzm = new Attachment();
      sfzzm.setName("SFZZM.jpg");
      String sfzzmBase64Content = Base64Utils
          .encodeToString(realNameAuth.getDocumentImgPositive().getBytes("utf-8"));
      sfzzm.setContent(sfzzmBase64Content);
      sfzzm.setSigndata(DigestUtils
          .sha256Hex(IOUtils.toByteArray(new URL(realNameAuth.getDocumentImgPositive()))));
      attachments.add(sfzzm);

      if (RIGHT_OWN_MODE_PERSONAL_WORKS == copyRightWorks.getRightOwnMode()) {
        //原创声明书
        Attachment QLGS01 = new Attachment();
        QLGS01.setName("QLGS-01.pdf");
        ;
        String qlgs01Base64Content = Base64Utils
            .encodeToString(copyRightWorks.getOriginalStatement().getBytes("utf-8"));
        QLGS01.setContent(qlgs01Base64Content);
        QLGS01.setSigndata(DigestUtils
            .sha256Hex(IOUtils.toByteArray(new URL(copyRightWorks.getOriginalStatement()))));
        attachments.add(QLGS01);
        //身份证反面
        Attachment sfzfm = new Attachment();
        sfzfm.setName("SFZFM.jpg");
        String sfzfmBase64Content = Base64Utils
            .encodeToString(realNameAuth.getDocumentImgBack().getBytes("utf-8"));
        sfzfm.setContent(sfzfmBase64Content);
        sfzfm.setSigndata(
            DigestUtils.sha256Hex(IOUtils.toByteArray(new URL(realNameAuth.getDocumentImgBack()))));
        attachments.add(sfzfm);

      } else {
        //法人作品品证明
        Attachment QLGS0804 = new Attachment();
        QLGS0804.setName("QLGS-0804.pdf");
        String qlgs0804Base64Content = Base64Utils
            .encodeToString(copyRightWorks.getLegalCreationStatement().getBytes("utf-8"));
        QLGS0804.setContent(qlgs0804Base64Content);
        QLGS0804.setSigndata(DigestUtils
            .sha256Hex(IOUtils.toByteArray(new URL(copyRightWorks.getLegalCreationStatement()))));
        attachments.add(QLGS0804);

        //证件反面
        Attachment sfzfm = new Attachment();
        sfzfm.setName("SFZFM.jpg");
        sfzfm.setContent(sfzzmBase64Content);
        sfzfm.setSigndata(DigestUtils
            .sha256Hex(IOUtils.toByteArray(new URL(realNameAuth.getDocumentImgPositive()))));
        attachments.add(sfzfm);
      }

      return attachments;
    } catch (IOException e) {
      logger.error("获取附件信息错误", e);
      throw new BizException("获取附件信息错误");
    }
  }

  /**
   * 获取作品DNA
   */
  private String getWorksDna(CopyRightWorks copyRightWorks, String privateKey) {

    try {
      String contentUrl = copyRightWorks.getImageName();
      if (!StringUtil.isEmpty(copyRightWorks.getHuabanImageUrl())) {
        contentUrl = copyRightWorks.getHuabanImageUrl();
      }

      String base64Contnet = Base64Utils.encodeToString(IOUtils.toByteArray(new URL(contentUrl)));

      String contentHash = DTCPProcessor.GenContentHash(base64Contnet);

      Metadata metadata = new Metadata();
      metadata.setType("image");
      metadata.setTitle(copyRightWorks.getWorksFullName());
      metadata.setAbstractContent(copyRightWorks.getMainFeatures());
      metadata.setCategory(
          CategoryUtil.getCategoryName(copyRightWorks.getCategoryId()).replace("&", ","));
      metadata.setContentHash(contentHash);
      BlockHashQueryResp blockHashQueryResp = NodeProcessor
          .QueryLatestBlockHash(ybServerUrl);
      BlockHashResp blockHashResp = blockHashQueryResp.getData();
      String blockHash = blockHashResp == null ? "7622248F8FC7C96D377F73A6A01C5C8E23C762EC"
          : blockHashResp.getLatestBlockHash();
      metadata.setBlockHash(blockHash);
      Long blockHeight = blockHashResp == null ? 166729 : blockHashResp.getLatestBlockHeight();
      metadata.setBlockHeight(blockHeight.toString());
      Metadata.License license = new Metadata.License();
      license.setType("huaban-group");
      TreeMap<String, String> params = new TreeMap<>();
      params.put("outdoors", "true");
//      params.put("commercial", "n");
//      params.put("expire",String.valueOf(DateUtil.getOffsiteDate(new Date(), Calendar.YEAR, 10).getTime()));
      license.setParameters(params);
      metadata.setLicense(license);
      if (!StringUtil.isEmpty(copyRightWorks.getDna())) {
        metadata.setParentDna(copyRightWorks.getDna());
      }
      ImageInfo imageInfo;
      if (StringUtil.isEmpty(copyRightWorks.getHuabanImageUrl())) {
        imageInfo = getImageInfo(copyRightWorks.getImageName());
      } else {
        imageInfo = new ImageInfo();
        URL url = new URL(copyRightWorks.getHuabanImageUrl());
        URLConnection connection = url.openConnection();
        connection.setDoOutput(true);
        InputStream inputStream = connection.getInputStream();
        BufferedImage image = null;
        try {
          image = ImageIO.read(inputStream);
          imageInfo.setImageHeight(image.getHeight());
          imageInfo.setImageWidth(image.getWidth());

        } catch (IOException e) {
          logger.error("读取图片信息异常", e);
        }
        imageInfo.setFormat("jpg");
        imageInfo.setFileSize(connection.getContentLength());

      }

      TreeMap<String, String> dataMap = new TreeMap<>();
      dataMap.put("thumb", copyRightWorks.getImageName() + "?x-oss-process=style/large_style_h");
      dataMap.put("original", copyRightWorks.getImageName());
      dataMap.put("ext", imageInfo.getFormat());
      dataMap.put("width", String.valueOf(imageInfo.getImageWidth()));
      dataMap.put("height", String.valueOf(imageInfo.getImageHeight()));
      dataMap.put("size", String.valueOf(imageInfo.getFileSize()));
      metadata.setData(dataMap);
      TreeMap<String, String> extraData = new TreeMap<>();
      extraData.put("author", copyRightWorks.getAuthor());
      metadata.setExtra(extraData);

      Metadata fullMetadata = DTCPProcessor.FullMetadata(privateKey, metadata);
      logger.info("metaData内容{}", JSON.toJSONString(fullMetadata));
      MetadataSaveResp metadataSaveResp = NodeProcessor
          .SaveMetadata(ybServerUrl, fullMetadata);
      logger.info("获取原本dna结果{}", JSON.toJSONString(metadataSaveResp));
      if (metadataSaveResp.getData() == null) {
        throw new BizException(metadataSaveResp.getMsg());
      }
      return metadataSaveResp.getData().getDna();
    } catch (IOException e) {
      logger.error("获取图片文件异常", e);
      throw new BizException("获取图片异常");
    } catch (InvalidException e) {
      logger.error("写入区块链异常", e);
      throw new BizException("写入区块链信息异常");
    }
  }

  private ImageInfo getImageInfo(String imageUrl) {
    ImageInfo imageInfo;
    if (imageUrl
        .startsWith("http://meisudci.oss-cn-beijing.aliyuncs.com")) {
      imageInfo = ossService.getImageInfo(imageUrl
          .replace("http://meisudci.oss-cn-beijing.aliyuncs.com/", ""));
    } else {
      imageInfo = new ImageInfo();
      Response response = HttpClient
          .get(imageUrl + "?x-oss-process=image/info", null);
      if (response.getStatusCode() == 200) {
        String content = response.getContent();
        JSONObject jsonObject = JSON.parseObject(content);
        String imageHeight = jsonObject.getJSONObject("ImageHeight").getString("value");
        String imageWidth = jsonObject.getJSONObject("ImageWidth").getString("value");
        String imageSize = jsonObject.getJSONObject("FileSize").getString("value");
        String imageFormat = jsonObject.getJSONObject("Format").getString("value");
        imageInfo.setFormat(imageFormat);
        imageInfo.setFileSize(Integer.valueOf(imageSize));
        imageInfo.setImageWidth(Integer.valueOf(imageWidth));
        imageInfo.setImageHeight(Integer.valueOf(imageHeight));
      }
    }
    return imageInfo;
  }

  private void sendMessageRegSucc(String worksFullName, Long worksId, Long userId) {
    String title = String.format("您已成功提交《%s》作品版权登记申请", worksFullName);
    String content = String
        .format("您已经成功提交《%s》作品版权登记申请，中国版权保护中心正在审核申请材料，请注意查收短信或站内消息提醒。", worksFullName);
    messageService.addMessage(title, content, userId, worksId);
  }

  private void sendMessagePassed(String worksFullName, Long worksId, Long userId, String dciCode) {
    String title = String.format("《%s》已通过中国版权保护中心审核", worksFullName);
    String content = String
        .format("《%s》已通过中国版权保护中心审核并在美素交易平台上架销售，作品DCI：%s。您可在个人中心查看作品销售情况。", worksFullName, dciCode);
    messageService.addMessage(title, content, userId, worksId);
  }

  private void sendSmsPassed(String worksFullName, Long userId) {
    String content = String
        .format("【美素版权】《%s》已通过中国版权保护中心审核并在美素交易平台上架销售。您可登录美素版权平台查看作品销售情况。", worksFullName);
    Users user = usersRepo.findOne(userId);
    if (!StringUtil.isEmpty(user) && !StringUtil.isEmpty(user.getMobile())) {
      salesService.sendMessage(user.getMobile(), content);
    }
  }

  private void sendMessageRejected(String worksFullName, Long worksId, Long userId) {
    String title = String.format("《%s》未通过中国版权中心审核", worksFullName);
    String content = String.format("《%s》未通过中国版权保护中心审核，请进行修改并重新提交。", worksFullName);
    messageService.addMessage(title, content, userId, worksId);

  }

  private void sendSmsRejected(String worksFullName, Long userId) {
    String content = String.format("【美素版权】《%s》未通过中国版权保护中心审核，请进行修改并重新提交。", worksFullName);
    Users user = usersRepo.findOne(userId);
    if (!StringUtil.isEmpty(user) && !StringUtil.isEmpty(user.getMobile())) {
      salesService.sendMessage(user.getMobile(), content);
    }
  }

  private void hbNotify(int status, long user_id, String huaban_url, String url, String message,
      String dci, String cert, Long worksId) {
    Map<String, String> params = new HashMap<>();
    params.put("status", String.valueOf(status));
    params.put("user_id", String.valueOf(user_id));
    params.put("huaban_url", huaban_url);
    params.put("url", url);
    params.put("worksId", String.valueOf(worksId));
    if (!StringUtil.isEmpty(message)) {
      params.put("message", message);
    }
    if (!StringUtil.isEmpty(dci)) {
      params.put("dci", dci);
    }
    if (!StringUtil.isEmpty(cert)) {
      params.put("cert", cert);
    }
    notifyQueue.addElementToList(params, 1, hbCallBackUrl);
  }

  private void clientNotify(boolean status, String dciUrl, String message, String dci, String cert,
      Long worksId) {
    RegisterCallBackParamsVo paramsVo = new RegisterCallBackParamsVo();
    paramsVo.setCertFileUrl(cert);
    paramsVo.setDci(dci);
    paramsVo.setDciUrl(dciUrl);
    paramsVo.setErrorDesc(message);
    paramsVo.setId(worksId);
    paramsVo.setSuccess(status);

    BeanMap map = BeanMap.create(paramsVo);
    Map<String, String> params = new HashedMap();
    for (Object key : map.keySet()) {
      String putKey = String.valueOf(key);
      Object putValue = map.get(key);
      params.put(putKey, String.valueOf(putValue));
    }
    notifyQueue.addElementToList(null, 1, clientCallbackUrl);

  }

  private void analyzingApplyPushed(RealNameAuth realNameAuth) {
    String url = dciServerUrl + "/checkapplyer.do";
    Map<String, String> params = new HashMap<>();
    params.put("caid", realNameAuth.getAccountId());
    Response response = HttpClient.get(url, params);
    String content = response.getContent();
    JSONObject jsonResult = JSON.parseObject(content);
    if (1 == jsonResult.getInteger("flag")) {
      realNameAuthService.pushApplyerToDci(realNameAuth);
    }
  }
}
